<?php
/**
 * Notes: 导入的公共方法调取模块，供各个模块的导入， 进行数据查询和处理
 * 需要提供一个方法，保存对应的缓存信息，如果缓存数据已经存在，则先检索缓存数据，不存在则进行数据库查询
 * Author: lizhongjie  2021-11-21
 *
 */

namespace Xtsb\Cims\Excel;

use Xtsb\Cims\Error\ApiErrorDesc;
use Xtsb\Cims\Exception\ApiException;
use Xtsb\Cims\Member\Member;
use app\Http\Epc\Servers\ProjectTypeServer;
use app\Http\Goods\Servers\GoodsSupplierServer;
use think\facade\Db;

class Import
{
  //检查表头， 表头必须全部都有文字，且必须与系统定义保持一致
  public static function getTitleInfo(&$response, $keyArray)
  {
    $title_arr = [];
    $key = 0;
    if (!$response)
      throw new ApiException(ApiErrorDesc::ERROR_DEFAULT,'无法读取excel表格数据，可能是文件损坏/开启了文件私密保护，请确认');

    foreach ($response as $column => $item) {
      if (!key_exists($key, $keyArray)) {
        if ($item) {
          return json('第' . $column . '列: 超出了导入列数限制，请将' . $column . '列之后的数据全部清除', 0);
        } else {
          unset($response[$column]);
        }
        continue;
      }
      $title_arr[$keyArray[$key]] = $item;
      $key++;
    }

    if (count($response) != count($keyArray))
      throw new ApiException(ApiErrorDesc::ERROR_DEFAULT,'导入表格有更新，请导出数据后，按照导出表格进行修改');

    return $title_arr;
  }

  //检索导入的部门是否存在，并返回部门的id以及上级机构id
  public static function getDM($break_message, $r_key, &$arr, $data, $key, $append = '')
  {
      if (!isset($arr[$data[$key]])) {
        $arr = explode('/',$data[$key]);
        for ($i = count($arr) - 1; $i >= 0; $i--){
          $data[$key] = trim($arr[$i]);
          break;
        }
        //优先从本机构查找
        $dm_info = Db::name('dm')->field('id dm_id, branch_id')->where(['cuid' => CUID, 'branch_id'=>BRANCHID])
          ->where('title', $data[$key])->find();
        if (!$dm_info){
          //否则全局查找
          $dm_info = Db::name('dm')->field('id dm_id, branch_id')->where(['cuid' => CUID])
            ->where('title', $data[$key])->find();
          //不存在报错
          if(!$dm_info)
            throw new ApiException(ApiErrorDesc::ERROR_DEFAULT,
              self::commonMessageBreak($break_message, $r_key, $append . '归属部门（' . $data[$key] . '）不存在，请先创建') );
        }
        $arr[$data[$key]] = $dm_info;
        return $dm_info;
      }else{
        return $arr[$data[$key]];
      }
  }
	
	/**
	 * 检索导入的部门是否存在，并返回部门的id以及上级机构id
	 * @param        $break_message
	 * @param        $r_key
	 * @param        $arr
	 * @param        $data
	 * @param        $dm_key
	 * @param        $branch_key
	 * @param string $append
	 * @return array|mixed|Db|\think\Model|null
	 * @throws \think\db\exception\DataNotFoundException
	 * @throws \think\db\exception\DbException
	 * @throws \think\db\exception\ModelNotFoundException
	 */
  public static function getBranchDM($break_message, $r_key, &$arr, $data, $dm_key, $branch_key, $append = '')
  {
      if (!isset($arr[$data[$branch_key].$data[$dm_key]])) {
        $dm_info = Db::name('dm')->alias('dm')
	        ->field('dm.id dm_id, dm.branch_id')
	        ->leftJoin('branch b', 'b.id = dm.branch_id')
	        ->where(['dm.cuid' => CUID, 'b.title' => $data[$branch_key]])
          ->where('dm.title', $data[$dm_key])->find();
        if (!$dm_info){
					if (empty($data[$branch_key])) {
						throw new ApiException(ApiErrorDesc::ERROR_DEFAULT,
							self::commonMessageBreak($break_message, $r_key, $append . '归属机构（' . $data[$dm_key] . '）不空') );
					} else if (empty($data[$dm_key])) {
		        throw new ApiException(ApiErrorDesc::ERROR_DEFAULT,
			        self::commonMessageBreak($break_message, $r_key, $append . '归属部门（' . $data[$dm_key] . '）不空') );
	        } else
						//不存在报错
            throw new ApiException(ApiErrorDesc::ERROR_DEFAULT,
              self::commonMessageBreak($break_message, $r_key,
	              $append . '归属机构（'.$data[$branch_key].'）或归属部门（' . $data[$dm_key] . '）不存在，请先创建') );
        }
        $arr[$data[$branch_key].$data[$dm_key]] = $dm_info;
        return $dm_info;
      }else{
        return $arr[$data[$branch_key].$data[$dm_key]];
      }
  }

  //检索导入的人员是否存在，如果同时导入部门，检索对应人员的部门是否正确
  public static function getUser($break_message, $index, &$arr, $data, $key)
  {

    if (!isset($arr[$data[$key]])) {
      $where = [
        ['g.name', '=', $data[$key]],
      ];
      $temp = Db::table(USER_TABLE)->alias('g')
        ->field('g.uid, g.dm_id, g.branch_id, IFNULL(dm.title, "无部门") title, g.uuid')
        ->leftJoin('dm', 'dm.id = g.dm_id')
        ->where($where)->find();
      if (!$temp)
        throw new ApiException(ApiErrorDesc::ERROR_DEFAULT,
          self::commonMessageBreak($break_message, $index,
            '（' . $data[$key] . '）不存在，请先前往花名册新建，并给其开通账号' ));
      else if ($temp['uuid'] == -1)
        throw new ApiException(ApiErrorDesc::ERROR_DEFAULT,
          self::commonMessageBreak($break_message, $index,
            '请先给（' . $data[$key] . '）开通账号' ));
      $arr[$data[$key]] = $temp;
    }
    return $arr[$data[$key]]['uid'];
  }

  //检索导入上游单位
  public static function getSupplier(&$arr, $data, $key, $supplierType)
  {
    if(!$data[$key])
      return 0;
    if (!isset($arr[$data[$key]])) {
      $temp = Db::name('goods_supplier')
        ->field('id,title,account_name,tel,bank,address,tax_no,account_no')
        ->where(['cuid' => CUID])
        ->where('title', $data[$key])->find();
      if (!$temp) {
        $insert_data =['title' => $data[$key], 'account_name' => $data[$key]];
        if($supplierType == 'firstParty'){
          $temp = Member::createFirstParty($insert_data);
        }else{
          dump("公共方法需要适配");die;
        }
        $temp = ['id' => $temp, 'title' => $data[$key], 'account_name' => $data[$key]];
      } else if (!$temp['account_name']) {
        Db::name('goods_supplier')->where('id', $temp['id'])->update(['account_name' => $data[$key]]);
        $temp['account_name'] = $data[$key];
      }
      $arr[$data[$key]] = $temp;
    }
    return $arr[$data[$key]]['id'];
  }

  // getSupplier2 对getSupplier的重新实现-仅为防止出错 TODO 后续需要因为$donor 改写处理
  // 检索导入的供应商、甲方/上游单位、下游单位是否存在，如果不存在，则自动进行新增处理
  // donor: 0: 材料供应商  1：甲方/上游单位 2.乙方/下游单位
  private static function getSupplier2(&$arr, $data, $key, $donor){
    if(!$data[$key])
      return 0;

    $id = null;
    $tmp = null;
    switch (intval($donor)){
      case 1:
        $id = Member::createFirstParty($data,$key);
        break;
      case 2:
        $id =  Member::createDownstream($data,$key);
        break;
      case 0:
        $id =  Member::createSupplier($data,$key);
        break;
    }

    if($id>0){
      $tmpWhere[] = ['id','=',$id];
      $tmp = Db::name('goods_supplier')->field('id,title,account_name,tel,bank,address,tax_no,account_no')->where($tmpWhere)->find();
    }
    if(!empty($tmp)){
      $arr[$data[$key]] = $tmp;
    }

    return $id;
  }

  //获取合同信息
  public static function insertCca(&$arr, $data, $key_title, $key_order_no, $insert_info)
  {
    if (!$key_title && !$key_order_no)
      return null;

    if (!$data[$key_title] && !$data[$key_order_no])
      return null;

    $key = isset($data[$key_title]) ? $data[$key_title] : '';
    $key .= isset($data[$key_order_no]) ? $data[$key_order_no] : '';

    if (!isset($arr[$key])) {

      $where['cuid'] = CUID;
      if ($key_title && $data[$key_title])
        $where['title'] = $data[$key_title];
      else if ($key_order_no && $data[$key_order_no])
        $where['order_no'] = $data[$key_order_no];

      $temp = Db::name('cca')->field('id, title, order_no, branch_id, dm_id, project_manager_id, goods_supplier_id,manage_mode, is_multi')->where($where)->find();
      if (!$temp) {
        $temp = Db::name('cca')->json(['project_addr'])->insertGetId($insert_info);
        Db::name('cca_stats')->insert(['cca_id' => $temp]);
        $temp = Db::name('cca')->field('id, title, order_no, branch_id, dm_id, project_manager_id, goods_supplier_id,manage_mode, is_multi')->where('id', $temp)->find();
      }
      $arr[$key] = $temp;
    }
    return $arr[$key];
  }

  //获取工程项目信息, 不同合同下，工程名称可能相同，因此需要额外的cca_id作为前缀进行区分
  public static function insertCor(&$arr, $data, $key_title, $key_cor_no, $cca_id, $insert_info)
  {
    if (!$key_title && !$key_cor_no)
      return null;

    if (!$data[$key_title] && !$data[$key_cor_no])
      return null;

    $key = isset($data[$key_title]) ? $data[$key_title] : '';
    $key .= isset($data[$key_cor_no]) ? $data[$key_cor_no] : '';

    $insert_info['cca_id'] = $cca_id;
    if (!isset($arr[$cca_id . '+++' . $key])) {

      $where['cuid'] = CUID;
      $where['cca_id'] = $cca_id;
      if ($key_cor_no && $data[$key_cor_no])
        $where['cor_no'] = $data[$key_cor_no];
      if ($key_title && $data[$key_title])
        $where['title'] = $data[$key_title];

      $temp = Db::name('cor')->field('id, title, cor_no, branch_id, dm_id, project_manager_id, goods_supplier_id')->where($where)->find();
      if (!$temp) {
        $temp = Db::name('cor')->json(['project_addr'])->insertGetId($insert_info);
        Db::name('cor_stats')->insert(['cor_id' => $temp]);
        $temp = Db::name('cor')->field('id, title, cor_no, branch_id, dm_id, project_manager_id, goods_supplier_id')->where('id', $temp)->find();
  
      }
      $arr[$cca_id . '+++' . $key] = $temp;
    }
    return $arr[$cca_id . '+++' . $key];
  }

  public static function getCorInfo(&$arr, $title, $cor_no, $manage_mode = null, $field = null)
  {


    if (!$field)
      $field = 'id, branch_id, dm_id, manage_mode,project_manager_id,project_type,goods_supplier_id,status';

    $cor_info = null;
    $key = '';
    $where[] = ['cuid', '=', CUID];
    if ($title) {
      $key .= $title;
      $field.=',title';
      $where[] = ['title', '=', $title];
    }
    if ($cor_no) {
      $key .= $cor_no;
      $field.=',cor_no';
      $where[] = ['cor_no', '=', $cor_no];
    }

    if (!isset($arr[$key])) {
      $cor_info = Db::name('cor')->field($field)->where($where)->find();
      if ($cor_info) {
        if(empty($cor_info['title']) || $cor_info['title'] <> $title || (!empty($cor_info['cor_no']) && $cor_info['cor_no'] <> $cor_no)){
          return null;
        }
        if ($cor_info['status'] != 2) {
          throw new ApiException(ApiErrorDesc::ERROR_DEFAULT,'工程必须审核完毕之后，才能导入工程内容，请等待工程审批完成。');
        }
        if ($manage_mode) {
          if ($cor_info['manage_mode'] != $manage_mode){
            throw new ApiException(ApiErrorDesc::ERROR_DEFAULT,'工程管理模式不正确，请检查。');
          }
        }
        $arr[$key] = $cor_info;
      } else {
//        throw new ApiException(ApiErrorDesc::ERROR_DEFAULT,'工程不存在，请先创建。');
      }
    } else {
      $cor_info = $arr[$key];
    }
    return $cor_info;

  }
  
  public static function getCorOrCcaId($break_message, $r_key, &$project_arr, $project_title, &$item){
  
    if(!isset($project_arr[$item[$project_title]])){
      $project_id = Db::name('cor')->where('cuid', CUID)->where('title', $item[$project_title])->value('id');
      if (!$project_id) {
        $project_id = Db::name('cca')->where('cuid', CUID)->where('title', $item[$project_title])->value('id');
        if($project_id){
          $project_arr[$item[$project_title]] = ['key'=>'cca_id', 'value'=>$project_id];
        }else{
          throw new ApiException(ApiErrorDesc::ERROR_DEFAULT,
            Import::commonMessageBreak($break_message, $r_key,
              $item[$project_title] . '： 项目信息不存在，请先新建合同/工程订单'));
        }
      }else{
        $project_arr[$item[$project_title]] = ['key'=>'cor_id', 'value'=>$project_id];
      }
    }
    $item[$project_arr[$item[$project_title]]['key']] = $project_arr[$item[$project_title]]['value'];
    return $project_arr[$item[$project_title]];
  }

  //根据导入的省市区数据，进行地址数据组装，并回填至$data
  public static function getAddress($r_key, &$data, &$province_arr, &$city_arr, &$county_arr, $up_branch_info = null)
  {
    $data['project_addr'] = [];
    $address_list = [];
    if (isset($data['province']) && $data['province']) {
      $temp = explode("\n", $data['province']);
      foreach ($temp as $item) {
        if (!isset($province_arr[$item])) {
          $province = Db::name('address')->whereLike('province', '%' . $item . '%')->value('province');
          if ($province) {
            $province_arr[$item] = $province;
            if ($item != $province)
              $province_arr[$province] = $province;
          } else {
            throw new ApiException(ApiErrorDesc::ERROR_DEFAULT, '导入的表格第【' . $r_key . '】行：' . $item . '=>省份名称不存在');

          }
        } else {
          $province = $province_arr[$item];
        }
        if (!isset($address_list[$province]))
          $address_list[$province] = [];
      }

    }

    if (isset($data['city']) && $data['city']) {
      $temp = explode("\n", $data['city']);

      foreach ($temp as $item) {
        if (!isset($city_arr[$item])) {
          $city_info = Db::name('address')->field('province, city')->whereLike('city', '%' . $item . '%')->find();
          if ($city_info) {
            $province_arr[$city_info['province']] = $city_info['province'];
            $city_arr[$item] = $city_info;
            if ($item != $city_info['city'])
              $city_arr[$city_info['city']] = $city_info;
            $city_all[] = $city_info['city'];
          } else {
            throw new ApiException(ApiErrorDesc::ERROR_DEFAULT, '导入的表格第【' . $r_key . '】行：' . $item . '=>地市名称不存在');
          }
        } else {
          $city_info = $city_arr[$item];
        }

        if (!isset($address_list[$city_info['province']][$city_info['city']]))
          $address_list[$city_info['province']][$city_info['city']] = [];
      }
    }

    if (isset($data['county']) && $data['county']) {
      $temp = explode("\n", $data['county']);
      foreach ($temp as $item) {
        if (!isset($county_arr[$item])) {
          $county_info = Db::name('address')->field('province, city, county')->whereLike('county', '%' . $item . '%')->select()->toArray();
          if (count($county_info) == 1) {
            $county_info = $county_info[0];
            $county_arr[$item] = $county_info;
            if ($item != $county_info['county'])
              $county_arr[$county_info['county']] = $county_info;

          } else if (count($county_info) > 1) {
            $county_info = Db::name('address')->field('province, city, county')->where('county',  $item )->select()->toArray();
            if (count($county_info) == 1) {
              $county_info = $county_info[0];
              $county_arr[$item] = $county_info;
              if ($item != $county_info['county'])
                $county_arr[$county_info['county']] = $county_info;
            }else{
              $hit = -1;
              if ($up_branch_info && $up_branch_info['project_addr']) {
                foreach ($county_info as $key1 => $item1) {
                  foreach ($up_branch_info['project_addr'] as $item2) {
                    if ($item2['province'] == $item1['province'] && ($item2['city'] == $item1['city'])) {
                      $hit = $key1;
                      break;
                    }
                  }
                  if ($hit > -1)
                    break;
                }
              }
  
              if ($hit > -1) {
                $county_info = $county_info[$hit];
    
              } else {
                throw new ApiException(ApiErrorDesc::ERROR_DEFAULT, '导入的表格第【' . $r_key . '】行：' . $item . '=>区县重复，请补充填写城市名称');
              }
            }
            

          } else {
            throw new ApiException(ApiErrorDesc::ERROR_DEFAULT, '导入的表格第【' . $r_key . '】行：' . $item . '=>区县名称不存在');
          }
        } else
          $county_info = $county_arr[$item];
        $address_list[$county_info['province']][$county_info['city']][] = $county_info['county'];
      }
    }

    $data['project_addr'] = [];
    if ($address_list) {
      foreach ($address_list as $province => $item) {
        $temp = ['province' => $province, 'city' => '', 'county' => ''];
        if ($item) {
          foreach ($item as $city => $item1) {
            $temp['city'] = $city;
            if ($item1) {
              foreach ($item1 as $county) {
                $temp['county'] = $county;
                $data['project_addr'][] = $temp;
              }
            } else {
              $data['project_addr'][] = $temp;
            }
          }
        } else {
          $data['project_addr'][] = $temp;
        }
      }
    }
    unset($data['province']);
    unset($data['city']);
    unset($data['county']);
    return true;
  }

  public static function getProjectManageList(&$data, $key, $desc = '甲方项目经理', $clear = true)
  {
    if ($data[$key]) {
      $list['desc'] = $desc;

      $temp = explode('.', $data[$key]);
      $list['name'] = $temp[0];
      $list['mobile'] = isset($temp[1]) ? $temp[1] : '';
      unset($temp[0]);
      unset($temp[1]);
      $list['email'] = '';
      if ($temp) {
        $list['email'] = implode('.', $temp);
      }

      $data['project_manager_list'][] = $list;
    }
    if ($clear)
      unset($data[$key]);
  }

  public static function mergeProjectManageList(&$project_manager_list, $exist_info)
  {

    $name_list = [];
    if ($exist_info)
      foreach ($exist_info as $key => $item) {
        $list[$item['name']] = $key;
      }

    if ($project_manager_list) {
      foreach ($project_manager_list as $item) {
        if (isset($name_list[$item['name']])) {
          $exist_info[$name_list[$item['name']]] = $item;
        } else
          $exist_info[] = $item;
      }
    }
    $project_manager_list = $exist_info;

  }

  public static function messageBreak($all, $new, $update, $ng_message = null)
  {

    $message = ["共导入" . $all . "条数据"];
	  $new = is_numeric(intval($new)) ? $new : 0;
	  $message[] = "<span class='text-green'>" . $new . "条数据插入成功 </span>";
	  $update = is_numeric(intval($update)) ? $update : 0;
	  $message[] = "<span class='text-green'>" . $update . "条数据更新成功 </span>";
    if ($ng_message)
      $message[] = $ng_message;


    return implode("<br>", $message);

  }
  
  public static function commonMessageBreak($message_arr, $row=null, $error_message=null){
    $message = [];
    if($message_arr){
      foreach ($message_arr as $item){
        if($item['count']>0){
          if(isset($item['class'])){
            $temp = "<span class='".$item['class']."'>" .$item['pre'].$item['count'].$item['append']."</span>";
          }else{
            $temp = $item['pre'].$item['count'].$item['append'];
          }
          if(!empty($item['message_arr'])){
            $temp .= '<br>'.implode('<br>', $item['message_arr']);
          }
          $message[] = $temp;
        }
      }
    }
    if($error_message){
      if($row){
        $message[] = "<span class='text-red'>【导入中断】导入的表格第【".$row."】行发生错误，请修改表格数据</span><br>错误描述信息："."" .$error_message."";
      }else{
        $message[] = "<span class='text-red'>【导入中断】错误描述信息： " .$error_message."</span>";
      }
    }
    else if(!$message)
      $message=['没有导入任何数据'];
    return implode("<br>", $message);
    
  }

  public static function getTeamInfo($r_key, &$arr, $title)
  {
    if (!isset($arr[$title])) {
      $info = Db::name('team')->field('id, available')->where('cuid', CUID)->where('title', $title)->find();
      if (!$info){
        throw new ApiException(ApiErrorDesc::ERROR_DEFAULT,'导入的表格第【' . $r_key . '】行：' . $title . '=>工程队不存在');
      }
      else if ($info['available'] != 2){
  
        throw new ApiException(ApiErrorDesc::ERROR_DEFAULT,'导入的表格第【' . $r_key . '】行：' . $title . '=>工程队已经被禁用');
      }
      $arr[$title] = $info;
    } else {
      $info = $arr[$title];
    }
    return $info;
  }
  
  public static function checkProjectExist($r_key, &$arr,&$temp_arr, $table_name, $project_key, $project_desc){
    if($arr[$project_key]){
      $temp = $temp_arr[$table_name.'_'.$arr[$project_key]]??null;
      if(!$temp){
        $where[] = ['title', '=', $arr[$project_key]];
        $where[] = ['cuid', '=', CUID];
        if($table_name=='cor' && !empty($arr['cca_id'])){
          $where[] = ['cca_id', '=', $arr['cca_id']];
        }else if($table_name=='project_ledger' && !empty($arr['cor_id']) ){
          $where[] = ['cor_id', '=', $arr['cor_id']];
        }
        $info =Db::name($table_name)->where($where)->select()->toArray();
  
        if(!$info){
          throw new ApiException(
            ApiErrorDesc::ERROR_DEFAULT,"<span class='text-red'>导入的表格第{$r_key}行：{$project_desc}【{$arr[$project_key]}】不存在</span>"
          );
        }
        if(count($info)>1){
          throw new ApiException(
            ApiErrorDesc::ERROR_DEFAULT,"<span class='text-red'>导入的表格第{$r_key}行：{$project_desc}【{ $arr[$project_key]}】，存在多条数据，请输入其上一级项目名称</span>"
          );
        }
  
        $temp = $temp_arr[$table_name.'_'.$arr[$project_key]] =$info[0]['id'];
      }
      $arr[$project_key] =$temp;
    }
    return $info[0]??[];
  }
  
  public static function getBranchDmProjectMangerValue($msg, $value, &$data){
  
    $data['branch_id'] = $value['branch_id']??null;
    if(empty($data['branch_id'])){
      throw new ApiException(ApiErrorDesc::ERROR_DEFAULT,$msg . '请填写归属机构');
    }
    !empty($data['branch_id'])  and $data['branch_id'] = Db::name('branch')
      ->where('title', $data['branch_id'])->where('cuid', CUID)->value('id');
    if(empty($data['branch_id'])){
      throw new ApiException(ApiErrorDesc::ERROR_DEFAULT,$msg . '归属机构不存在');
    }
    $data['dm_id'] = $value['dm_id']??null;
    if(empty($data['branch_id'])){
      throw new ApiException(ApiErrorDesc::ERROR_DEFAULT,$msg . '请填写归属部门');
    }
    !empty($data['dm_id'])  and $data['dm_id'] = Db::name('dm')
      ->where('branch_id', $data['branch_id'])
      ->where('title', $data['dm_id'])->value('id');
    if(empty($data['dm_id'])){
      throw new ApiException(ApiErrorDesc::ERROR_DEFAULT,$msg . '归属部门不存在，请检查该部门是否存在');
    }
    $data['project_manager_id'] = empty($value['project_manager_id'])?null:$value['project_manager_id'];
    if(!empty($data['project_manager_id'])){
      if($data['project_manager_id'] == UNAME){
        $data['project_manager_id'] = UID;
      }else{
        $temp = Db::table(USER_TABLE)->alias('g')->where('g.name', $data['project_manager_id'])
          ->select()->toArray();
        if(count($temp) == 0){
          throw new ApiException(ApiErrorDesc::ERROR_DEFAULT,$msg . '项目经理不存在，请先给对应人员增加花名册并开通账号');
        }
        else if(count($temp) == 1){
          $data['project_manager_id'] = $temp[0]['uid'];
        }else{
  
          $temp1 = Db::table(USER_TABLE)->alias('g')->where('g.name', $data['project_manager_id'])
            ->where('g.dm_id', $data['dm_id'])
            ->select()->toArray();
          if(count($temp1) == 1){
            $data['project_manager_id'] = $temp1[0]['uid'];
          }else{
            foreach ($temp as $key=>$item){
              $temp[$key] = '所属机构：'.($item['branch_name']??'').'>所属部门：'.($item['dm_name']??'').'>'.$item['name'];
            }
            throw new ApiException(ApiErrorDesc::ERROR_DEFAULT,$msg . '项目经理重名，请检查归属机构、部门是否填写正确<br>'.
            implode('<br>', $temp));
          }
        }
      }
    }
  }

  public static function getDateValue($msg, $keyArray, $value, &$data){
  
    //校验日期格式并获取数据
    foreach ($keyArray as $item) {
      if(empty($value[$item])){
        $data[$item] = null;
      }else{
        $temp = $value[$item];
        $data[$item] = excel_time($value[$item]);
        if ($data[$item] == 'error') {
          !empty($temp) and $temp =  '(' . $temp . ')';
          throw new ApiException(
            ApiErrorDesc::ERROR_DEFAULT,
            $msg .$temp.' 日期格式不正确, 参考格式:<br> 1: 2020-01-01 <br>2: 2020/01/01 <br>3: 2020.01.01 <br>4: 不填写'
          );
        }
      }
    }
  
  }
  
  public static function getProjectTypeValue($msg, $value, &$data, &$project_type_arr){
  
    if(empty($value['project_type'])){
      $data['project_type'] = null;
    }else{
      $project_type_id = ProjectTypeServer::getProjectTypeData($project_type_arr, $value['project_type'], is_ceo());
      if (!$project_type_id) {
        throw new ApiException(
          ApiErrorDesc::ERROR_DEFAULT,$msg . '工程类型不存在，请先联系管理员进行工程类型新增'
        );
      }
      $data['project_type'] = $project_type_id;
    }
  
  }
  
  public static function getCcaIdValue($msg, $value, &$data, &$cca_arr, $cca_key=['cca_id', 'cca_order_no']){
    $cca_id = empty($value[$cca_key[0]])?null:$value[$cca_key[0]];
    $cca_order_no = empty($value[$cca_key[1]])?null:$value[$cca_key[1]];
    if($cca_id){
      $where[] = ['title', '=', $cca_id];
    }
    if($cca_order_no){
      $where[] = ['order_no', '=', $cca_order_no];
    }
    if(!empty($where)){
      $where[] = ['cuid', '=', CUID];
      $cca_id and $cca_title[] = $cca_id;
      $cca_order_no and $cca_title[] = $cca_order_no;
      $cca_title = implode('/', $cca_title);
      if(in_array($cca_title, $cca_arr)){
        $data['cca_id'] = $cca_arr[$cca_title];
      }else{
        $temp = Db::name('cca')->field('id, CONCAT_WS("", CONCAT("【合同名称】",title),CONCAT("【合同编号】",order_no)) label')
          ->where($where)
          ->select()->toArray();
        if(count($temp)==1){
          $data['cca_id'] = $temp[0]['id'];
        }else if(count($temp)==0){
          throw new ApiException(ApiErrorDesc::ERROR_DEFAULT,$msg ."{$cca_title}: 上游合同不存在");
        }else{
          throw new ApiException(ApiErrorDesc::ERROR_DEFAULT,$msg ."{$cca_title}:
 上游合同存在多个，请参考以下合同信息，进行填写，或直接修正已经存在的上游合同名称/编号<br>".
            implode('<br>', array_column($temp, 'label')));
        }
      }
    }
  }
  
  public static function getProjectMangerListValue($value, &$data, $separator='；', $sub_separator='，'){
    if(empty($value['project_manager_list'])){
      $data['project_manager_list'] = [];
    }else{
      $project_manager_list = explode($separator, $value['project_manager_list']);
      $i = 0;
      foreach ($project_manager_list as $key => $item) {
        $item = explode($sub_separator,$item);
        if (!empty($item[0]) || !empty($item[1]) || !empty($item[2]) || !empty($item[3])) {
          $project_manager_list[$key] = [
            'name' => $item[0] ?? null,
            'mobile' => $item[1] ?? null,
            'desc' => $item[2] ?? null,
            'email' => $item[3] ?? null,
            'sheet_id' => $i
          ];
          $i++;
        }
      }
      $data['project_manager_list'] = $project_manager_list;
    }
  }
  
  
  /**
   * 对导入的excel表头进行校验， 适用于导入时，没有对应keyArray的情况
   * @param $data 导出时，构造的表头data数据
   *若调用本方法，需要对style属性进行额外配置
   * 配置属性： needImportCheck = true，则会自动匹配该单元格的导入值，是否与导出时的值一致
   * 配置属性: importKeyConfig = [value=>'attrName', 'label'=>''], 代表导入时，该单元格有公共属性配置，需要获取，填充返回值： $config中
   * @param $respon 调用excel公共方法获取的excel的值
   * @param bool $remove_title 是否对$respon进行处理，移除表头数据
   * @return array
   */
  public static function excelTitleCheck($data, &$respon, $remove_title = true){
    $config = [];
    foreach ($data as $row => $title_row){
      $columnNumFirst = 65;
      $columnNumSecond = null;
      foreach ($title_row as $column_item){
        ##1. 带有导入格式校验标记位的，需要对导入的单元格数据，与默认做匹配， 不匹配的，返回
        if(!empty($column_item['style']['needImportCheck'])){
          $import_key = chr($columnNumFirst).($columnNumSecond?chr($columnNumSecond):'');
          if($column_item['value']!=$respon[$row+1][$import_key]){
            throw new ApiException(ApiErrorDesc::ERROR_DEFAULT,'导入模板不正确，请导出后， 在导出的excel中进行编辑，再导入');
          }
        }
        ##2. 带有导入公共配置标记位的，需要读取对应的导入数值，方便后续做处理
        if(!empty($column_item['style']['importKeyConfig'])){
          $import_key = chr($columnNumFirst).($columnNumSecond?chr($columnNumSecond):'');
          $temp =$column_item['style']['importKeyConfig'];
          $config[$temp['value']] = ['value'=>$respon[$row+1][$import_key], 'label'=>$temp['label']];
          unset($temp);
        }
        unset($import_key);
        
        ##3. 内部循环，对列数据进行递增
        if(empty($columnNumSecond)){
          $columnNumFirst+=$column_item['style']['colNum'];
          if($columnNumFirst>90){
            $columnNumFirst = 65;
            $columnNumSecond = 65+($columnNumFirst-91);
          }
        }
        else{
          $columnNumSecond+=$column_item['style']['colNum'];
          if($columnNumSecond>90){
            $columnNumFirst+=1;
            $columnNumSecond = 65+($columnNumSecond-91);
          }
        }
      }
  
      ##4. 移除表头数据
      if($remove_title){
        unset($respon[$row+1]);//导入的excel是从需要1开始的
      }
    }
    return $config;
  }


  ##项目相关数据的导入辅助数据获取， 进行项目名称、编号的拼接
  public static function getHelpListSet($respon, $table_name, $where, $keyRelation, $helpKeyRelation=null, $alias_table=[], $sepeartor=null){
    empty($sepeartor) and $sepeartor = '&|^';
    $keyFieldList = array_unique(array_column($respon, $keyRelation['response_field']));
    $label_query[] = $keyRelation['table_field'];

    if(!empty($helpKeyRelation)){
      foreach ($helpKeyRelation as $item){
        $label_query[] = "IFNULL({$item['table_field']}, '')";
      }
    }
    $label_query = implode(',', $label_query);

    $count = count($alias_table);

    if($count==0){
      $list =  Db::name($table_name)->alias('g')
        ->where('g.cuid', CUID)
        ->field("g.id value, CONCAT_WS('{$sepeartor}', $label_query) label")
        ->whereIn( $keyRelation['table_field'], $keyFieldList)
        ->where($where)
        ->select()->toArray();
    }else if($count == 1){

      $list =  Db::name($table_name)->alias('g')
        ->where('g.cuid', CUID)
        ->field("g.id value, CONCAT_WS('{$sepeartor}', $label_query) label")
        ->leftJoin($alias_table[0]['table_name'],$alias_table[0]['join'])
        ->whereIn( $keyRelation['table_field'], $keyFieldList)
        ->where($where)
        ->select()->toArray();
    }
    return array_column($list, 'value', 'label');
  }

  ##导入的数据，未进行列号转换， 按照序列字段关键字顺序，进行转换
  public static function responseKeyArraySet($keyArray, &$resonse){

    foreach ($resonse as $index=>$item){
      $temp = [];
      $i = 0;
      foreach ($item as $columnValue){
        $temp[$keyArray[$i]] = $columnValue;
        $i++;
      }
      $resonse[$index] = $temp;
    }

  }

  /**
   * 对数据进行往来单位的数据切换
   * @param $respon
   * @param $field  导入的字段
   * @param $new_field 需要设置的字段 
   * @param $type 往来单位类型
   * @throws \think\db\exception\DataNotFoundException
   * @throws \think\db\exception\DbException
   * @throws \think\db\exception\ModelNotFoundException
   */
  public static function setGoodsSupplierId(&$respon, $field, $type, $new_field=null){
    if(empty($new_field)){
      $new_field = $field;
    }
    $help_arr = Db::name('goods_supplier')->alias('g')
      ->field('g.id, g.title')
      ->leftJoin('goods_supplier_attr_access ga', "ga.goods_supplier_id = g.id and ga.attr_id={$type}")
      ->where('g.cuid', CUID)->whereIn('title', array_unique(array_column($respon, $field)))
      ->select()->toArray();
    $help_arr = array_column($help_arr, 'id', 'title');
    foreach ($respon as $r_key => $item) {
      if(empty($item[$field])){
        $respon[$r_key][$new_field] = null;
        continue;
      }
      if(empty($help_arr[$item[$field]])){
        $data = [
          'title'=>$item[$field],
          'type'=>$type,
        ];
        $id = Member::create($data);
        $help_arr[$item[$field]] = $id;
      }
      $respon[$r_key][$new_field] =  $help_arr[$item[$field]];
    }
  }

  ##根据传入的数据，匹配模板， 返回必填项提示
  public static function checkNeedField($respon, $need_field, $model, $message=null){
    foreach ($need_field as $field) {
      $is_array = is_array($field);
      if($is_array){
        $field_desc = [];
        foreach ($field as $field_item){
          $field_desc[] = $model[$field_item];
        }
        $field_desc = implode('/', $field_desc);
        $field_desc.= '(选填其中一项)';
      }else{
        $field_desc = $model[$field];
      }

      foreach ($respon as $r_key => $item) {
        if($is_array){
          $is_empty = true;
          foreach ($field as $field_item){
            if($is_empty){
              $is_empty = $is_empty&&empty($item[$field_item]);
            }else{
              break;
            }
          }
          if($is_empty){
            $error[$field_desc][] = $r_key;
          }
        }else{
          if (empty($item[$field])) {
            $error[$field_desc][] = $r_key;
          }
        }
      }
    }
    if(!empty($error)){
      $error_msg = [];
      foreach ($error as $key=>$item){
        $count = count($item);
        $error_msg[] = "【{$key}】共有".count($item).($message??"行")."未填写".
          ($count<20?('=><br>'.implode(',', $item)):'');
      }
      throw new ApiException(ApiErrorDesc::ERROR_DEFAULT,
        '必填数据项缺失，请参考以下列名、数据行数提示，进行补充填写，保存后再导入<br>'. implode('<br>', $error_msg));
    }
    unset($error);
    unset($need_field);
  }
  
  ##根据导入的部门、机构数据，自动回填数据
  public static function setDmId(&$respon, $branch_field, $dm_field, $new_branch_field=null, $new_dm_field=null){
    if(empty($new_branch_field)){
      $new_branch_field = $branch_field;
    }
    $help_arr = Db::name('branch')->alias('g')
      ->field('g.id, g.title')
      ->where('g.cuid', CUID)->whereIn('title', array_unique(array_column($respon, $branch_field)))
      ->select()->toArray();
    $help_arr = array_column($help_arr, 'id', 'title');
    foreach ($respon as $r_key => $item) {
      if(empty($help_arr[$item[$branch_field]])){
        $error_msg[] = $item[$branch_field];
      }
    }
    if(!empty($error_msg)){
      throw new ApiException(ApiErrorDesc::ERROR_DEFAULT,
        '以下机构不存在，请在组织管理菜单下，新增机构, 或者修改表格的机构名称<br>'.implode('<br>', array_unique($error_msg)));
    }
    if(empty($new_dm_field)){
      $new_dm_field = $dm_field;
    }
    $help_arr = Db::name('dm')->alias('g')
      ->field('g.id, CONCAT(b.title, ">", g.title) title')
      ->leftJoin('branch b', 'b.id = g.branch_id')
      ->where('g.cuid', CUID)->whereIn('g.title', array_unique(array_column($respon, $dm_field)))
      ->select()->toArray();
    $help_arr = array_column($help_arr, 'id', 'title');
    foreach ($respon as $r_key => $item) {
      $key = $item[$branch_field].'>'.$item[$dm_field];
      if(empty($help_arr[$key])){
        $error_msg[] = $key;
      }else{
        $respon[$r_key][$new_dm_field] = $help_arr[$key];
        unset($respon[$r_key][$branch_field]);
      }
    }
    if(!empty($error_msg)){
      throw new ApiException(ApiErrorDesc::ERROR_DEFAULT,
        '以下部门不存在，请在组织管理菜单下，新增部门, 或者修改表格的部门名称<br>'.implode('<br>', array_unique($error_msg)));
    }
  }

  
  ##导入的数据，已经进行了branch_id\dm_id的获取，根据branch_id\dm_id来匹配校验人员姓名
  public static function setUID(&$respon, $field, $new_field=null){
    if(empty($new_field)){
      $new_field = $field;
    }
    $help_arr = Db::name('staff')->alias('g')
      ->field('sa.id, CONCAT(IFNULL(sa.dm_id, ""), ">", g.name) name')
      ->leftJoin('staff_access sa', 'sa.staff_id = g.id')
      ->leftJoin('dm d', 'd.id = sa.dm_id')
      ->where('g.cuid', CUID)->whereIn('g.name', array_unique(array_column($respon, $field)))
      ->select()->toArray();
    $help_arr = array_column($help_arr, 'id', 'name');
    $help_dm_arr = Db::name('dm')->alias('g')
      ->field('id, title')
      ->where('g.cuid', CUID)->whereIn('id', array_unique(array_column($respon, 'dm_id')))
      ->select()->toArray();
    $help_dm_arr = array_column($help_dm_arr, 'title', 'id');
    foreach ($respon as $r_key => $item) {
      $key = $item['dm_id'].'>'.$item[$field];
      if(empty($help_arr[$key])){
        $error_msg[] = ($help_dm_arr[$item['dm_id']]??'').$item[$field];
      }else{
        $respon[$r_key][$new_field] = $help_arr[$key];
      }
    }
    if(!empty($error_msg)){
      throw new ApiException(ApiErrorDesc::ERROR_DEFAULT,
        '以下人员不存在，请在人事管理菜单下，新增该人员或者为其设置正确的部门，或者修改表格中的部门信息<br>'.implode('<br>', array_unique($error_msg)));
    }
  }
  ##导入的数据，不一定需要有u_id， 或者填写了用户姓名， 存在可能重名的情况，需要额外通过dm_title进行匹配识别
  public static function setUIDDmText($desc, &$respon, $field, $new_field=null,
                                      $dm_field='dm_id', $branch_field='branch_id'){
    if(empty($new_field)){
      $new_field = $field;
    }
    $help_arr = Db::name('staff')->alias('g')
      ->field('sa.id, g.name, d.title dm_name, b.title branch_name')
      ->leftJoin('staff_access sa', 'sa.staff_id = g.id')
      ->leftJoin('dm d', 'd.id = sa.dm_id')
      ->leftJoin('branch b', 'b.id = d.branch_id')
      ->where('g.name', '<>', '管理员')
      ->where('g.cuid', CUID)->whereIn('g.name', array_unique(array_column($respon, $field)))
      ->select()->toArray();
    ##1. 获取员工姓名对应的业务数据
    $temp = [];
    foreach ($help_arr as $item){
      $temp[$item['name']][] = $item;
    }
    $help_arr = $temp;
    unset($temp);
    ##2. 获取员工姓名\分支机构对应的业务数据(若存在重复数据)
    foreach ($help_arr as $name=>$item){
      if(count($item)>1){
        $temp = [];
        foreach ($item as $value){
          $temp[$value['branch_name']][$value['dm_name']][] = $value;
        }
        $help_arr[$name] = $temp;
      }
    }
    ##3. 对每行数据， 进行业务处理， 获取对应的人员UID
    foreach ($respon as $r_key => $item) {
      $name = $item[$field];
      if(empty($name)){
        $respon[$r_key][$new_field] = null;
        continue;
      }
      if(!isset($help_arr[$name])){
        $error['need_name'][] = $name;
        continue;
      }
      if(count($help_arr[$name])==1){
        $respon[$r_key][$new_field] = $help_arr[$name][0]['id'];
      }else{
        if(empty($item[$branch_field]) || empty($item[$dm_field])){
          $error['need_branch_dm'][] = $name;
          $error['need_branch_dm_key'][] = $r_key;
        }else{
          $temp = $help_arr[$name][$item[$branch_field]][$item[$dm_field]]??[];
          if(empty($temp)){
            $error['error_branch_dm'][] = $name;
            $error['error_branch_dm_key'][] = $r_key;
          }else{
            $respon[$r_key][$new_field] = $temp[0]['id'];
          }
        }
      }
    }
    if(!empty($error['need_name'])){
      $error['need_branch_dm'] = "以下{$desc}在系统中不存在(管理员不可作为业务操作人)，请重新填写<br>".
        implode('<br>', array_unique($error['need_name']));

      throw new ApiException(ApiErrorDesc::ERROR_DEFAULT,$error['need_branch_dm']);
    }
    if(!empty($error['need_branch_dm'])){

      $error['need_branch_dm'] = Db::name('staff')->alias('g')
        ->field('CONCAT_WS("  ", b.title, d.title, g.name) info')
        ->leftJoin('staff_access sa', 'sa.staff_id = g.id')
        ->leftJoin('dm d', 'd.id = sa.dm_id')
        ->leftJoin('branch b', 'b.id = d.branch_id')
        ->where('g.name', '<>', '管理员')
        ->where('g.cuid', CUID)->whereIn('g.name', array_unique( $error['need_branch_dm']))
        ->select()->toArray();

      $error['need_branch_dm'] = "以下{$desc}存在多个匹配岗位/人员，请补充填写<br>".
        "需要填写的excel位置(行)：".implode(',', $error['need_branch_dm_key'])."<br>相关人员的机构、部门信息参考如下：<br>".
        implode('<br>', array_column($error['need_branch_dm'], 'info'));

      throw new ApiException(ApiErrorDesc::ERROR_DEFAULT,$error['need_branch_dm']);

    }
    if(!empty($error['error_branch_dm'])){
      $error['error_branch_dm'] = Db::name('staff')->alias('g')
        ->field('CONCAT_WS("  ", b.title, d.title, g.name) info')
        ->leftJoin('staff_access sa', 'sa.staff_id = g.id')
        ->leftJoin('dm d', 'd.id = sa.dm_id')
        ->leftJoin('branch b', 'b.id = d.branch_id')
        ->where('g.name', '<>', '管理员')
        ->where('g.cuid', CUID)->whereIn('g.name', array_unique( $error['error_branch_dm']))
        ->select()->toArray();
      $error['error_branch_dm'] = "以下{$desc}对应的机构、部门不正确，请进行修改<br>".
        "需要修改的excel位置(行)：".implode(',', $error['error_branch_dm_key'])."<br>相关人员的机构、部门信息参考如下：<br>".
        implode('<br>', array_column($error['error_branch_dm'], 'info'));
      throw new ApiException(ApiErrorDesc::ERROR_DEFAULT,$error['error_branch_dm']);
    }
  }
  ##导入的数据，根据工程订单的名称，自动检索，若名称重复，提示需要填写合同名称进行二次定位， 并自动获取对应的数据
  public static function setCor(&$respon, $field, $new_field, $cca_field='cca_title',
                                $appendField=['g.dm_id'=>'dm_id', 'g.branch_id'=>'branch_id', 'g.goods_supplier_id'=>'goods_supplier_id']){

    $sql_field = '';
    $set_field = [];
    foreach ($appendField as $key=>$value){
      $sql_field.=", {$key} {$value}";
      $set_field[] = $value;
    }
    $help_arr = Db::name('cor')->alias('g')
      ->field('g.id, c.id cca_id, g.title, g.cor_no, g.order_no, c.title cca_title, c.order_no cca_order_no'.$sql_field)
      ->leftJoin('cca c', 'c.id = g.cca_id')
      ->where('g.cuid', CUID)
      ->whereIn('g.title', array_unique(array_column($respon, $field)))
      ->where('g.status', 2)->select()->toArray();

    ##1. 获取工程名称对应的业务数据
    $temp = [];
    foreach ($help_arr as $item){
      $temp[$item['title']][] = $item;
    }
    $help_arr = $temp;
    unset($temp);
    ##2. 获取工程对应的合同数据(若存在重复数据)
    foreach ($help_arr as $name=>$item){
      if(count($item)>1){
        $temp = [];
        foreach ($item as $value){
          $temp[$value['cca_title']][] = $value;
        }
        $help_arr[$name] = $temp;
      }
    }

    ##3. 对每行数据， 进行业务处理， 获取对应的cor_id
    foreach ($respon as $r_key => $item) {
      $name = $item[$field];
      if(empty($name)){
        $respon[$r_key][$new_field] = null;
        continue;
      }
      if(!isset($help_arr[$name])){
        $error['error_cor'][] = $name;
        continue;
      }
      if(count($help_arr[$name])==1){
        $respon[$r_key][$new_field] = $help_arr[$name][0]['id'];
        if($set_field){
          foreach ($set_field as $_v){
            $respon[$r_key][$_v] = $help_arr[$name][0][$_v];
          }
        }
      }else{
        if(empty($item[$cca_field])){
          $error['need_cca'][] = $name;
        }else{
          $temp = $help_arr[$name][$item[$cca_field]]??[];
          if(empty($temp)){
            $error['error_cca'][] = $name;
          }else{
            $respon[$r_key][$new_field] = $temp[0]['id'];
            if($set_field){
              foreach ($set_field as $_v){
                $respon[$r_key][$_v] = $temp[0][$_v];
              }
            }
          }
        }
      }
    }
    if(!empty($error['error_cor'])){
      $error['need_cca'] = "以下工程订单不存在，请修改工程订单名称<br>".
        implode('<br>', array_unique($error['error_cor']));

      throw new ApiException(ApiErrorDesc::ERROR_DEFAULT,$error['need_cca']);
    }
    if(!empty($error['need_branch_dm'])){
      $error['need_cca'] = Db::name('cor')->alias('g')
        ->field('CONCAT_WS("  ", c.title, g.title) info')
        ->leftJoin('cca c', 'c.id = g.cca_id')
        ->where('g.cuid', CUID)
        ->whereIn('g.title', array_unique($error['need_cca']))
        ->where('g.status', 2)->select()->toArray();

      $error['need_cca'] = "以下工程订单存在重名，请参考如下信息，补充填写工程订单的归属合同名称<br>".
        implode('<br>', array_column($error['need_cca'], 'info'));

      throw new ApiException(ApiErrorDesc::ERROR_DEFAULT,$error['need_branch_dm']);

    }
    if(!empty($error['error_cca'])){

      $error['error_cca'] = Db::name('cor')->alias('g')
        ->field('CONCAT_WS("  ", c.title, g.title) info')
        ->leftJoin('cca c', 'c.id = g.cca_id')
        ->where('g.cuid', CUID)
        ->whereIn('g.title', $error['need_cca'])
        ->where('g.status', 2)->select()->toArray();

      $error['need_cca'] = "以下工程订单存在重名，请参考如下信息，修改工程订单的归属合同名称<br>".
        implode('<br>', array_column($error['need_cca'], 'info'));

      throw new ApiException(ApiErrorDesc::ERROR_DEFAULT,$error['need_cca']);
    }
  }

  /**
   * 参数个数，表示，支持的excel列的最大拼接值， 2个： 最大为ZZ， 3个，最大为ZZZ
   * @param $columnNumFirst
   * @param $columnNumSecond
   */
  public static function columnNoNext(&$columnNumFirst, &$columnNumSecond){

    if(empty($columnNumSecond)){
      if($columnNumFirst==90){
        $columnNumFirst = 65;
        $columnNumSecond = 65;
      }else{
        $columnNumFirst++;
      }
    }
    else{
      if($columnNumSecond==90){
        $columnNumFirst++;
        $columnNumSecond = 65;
      }else{
        $columnNumSecond++;
      }
    }
  }
  public static function columnNoText($columnNumFirst, $columnNumSecond){
    return chr($columnNumFirst).($columnNumSecond?chr($columnNumSecond):'');
  }

  public static function responseKeyPlus(&$response, $append = 1){

    $temp =[];
    foreach ($response as $key=>$item){
      $temp[$key+$append] = $item;
    }
    $response = $temp;
    unset($temp);
  }
}
